package com.webserver.core;

import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.*;
import java.net.Socket;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;

/**
 * 客户端处理器类
 * <p>
 * 负责：
 * 1.实现Runnable接口
 * 2.处理客户端发送来的请求
 * 3.返回一个响应给客户端
 */
public class ClientHandler implements Runnable {
    //声明一个Socket准备接收与客户端连接的Socket对象
    private Socket socket;

    /**
     * ClientHandler的有参构造器
     * <p>
     * 负责： 初始化socket, 于客户端连接的Socket赋给它
     *
     * @param socket 与客户端连接的Socket
     */
    public ClientHandler(Socket socket) {
        //初始化socket, 将传入的socket赋给它
        this.socket = socket;
    }

    /**
     * 重写Runnable接口的void run()方法
     * <p>
     * 负责：
     * 1.处理客户端请求
     * 2.发送响应给客户端
     */
    @Override
    public void run() {
        System.out.println("客户端连接成功！");
        //开始解析客户端发送的请求
        try {
            //创建一个HttpServletRequest对象, 用于解析客户端的请求, 以及获取需要的请求解析信息
            HttpServletRequest request = new HttpServletRequest(socket);
            //创建一个HttpServletResponse对象, 用于给客户端发送响应, 以及设置响应相关属性
            HttpServletResponse response = new HttpServletResponse(socket);
            //获取到请求行中的抽象路径
            String url = request.getUrl();

            //获取 保存所有编译后文件 的根目录
            File root = new File(ClientHandler.class.getClassLoader().getResource(".").toURI());
            //获取 保存编译后静态资源文件的 的顶级目录
            File staticDir = new File(root, "static");

            //创建需要获取的静态文件的File变量
            File file = new File(staticDir, url);
            //若文件不存在, 统一获取404.html文件
            if (!file.exists()){
                file = new File(staticDir,"404.html");
                //将响应状态码设置好
                response.setStatusCode(404);
                //将响应状态描述设置好
                response.setStatusReason("NotFound");
            }
            //将要发送的文件设置好
            response.setStaticFile(file);

            //向浏览器发送响应
            response.response();
        } catch (IOException | URISyntaxException e) {
            e.printStackTrace();
        }
    }
}
